using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using snat.algorithms;
using snat.model;

namespace algorithms {
    public sealed partial class NodeFactorySet : IEnumerable<KeyValuePair<String, INodeFactory>> {

        public INodeFactory this[String algorithmName] {
            get {
                return Instance.Factories[algorithmName];
            }
        }

        private static volatile NodeFactorySet instance = new NodeFactorySet();
        public static NodeFactorySet Instance {
            get {
                return instance;
            }
        }

        private Dictionary<String, INodeFactory> Factories;
        private void Add(String name, INodeFactory algorithm) {
            int i = 1;
            while (Factories.ContainsKey(name)) {
                if (i > 1) {
                    name.Remove(name.Length - (i-1).ToString().Length);
                }
                name += i.ToString();
                i++;
            }
            Factories.Add(name, algorithm);
        }

        private NodeFactorySet() {
            Factories = new Dictionary<String, INodeFactory>();
        }

        public void Init() {
            Factories.Clear();
            try {
                UserInit();
            } catch (ArgumentException ex) {
                throw new FactoryNameException(@"There are two algorithms initialized in 
                                                 NodeFactorySet.UserInit() which have the same Name", ex);
            }
        }



        public IEnumerator<KeyValuePair<String, INodeFactory>> GetEnumerator() {
            foreach (KeyValuePair<String, INodeFactory> a in Factories) {
                yield return a;
            }

        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }
    }
}
